package org.oa.ai.utils;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletResponse;
import okhttp3.*;
import okio.BufferedSource;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.function.Consumer;
import java.util.logging.Logger;

public class HttpUtils {

    private static final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
            .readTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
            .writeTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
            .build();



    // 发送 POST JSON 请求
    public static JSONObject postJson(String url, String jsonBody, String token) throws IOException {

        Logger logger = Logger.getLogger(HttpUtils.class.getName());
        logger.info("Sending POST request to URL: " + url);

        RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + token)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                logger.warning("Unexpected response code: " + response);
                throw new IOException("Unexpected code " + response);
            }

            ResponseBody responseBody = response.body();
            if (responseBody == null){
                logger.warning("Empty response body");
                throw new IOException("Empty response body");
            }

            String responseString = responseBody.string();
            logger.info("开始=========================");
            System.out.println(responseString+"\n");
            logger.info("结束=========================");

            return new JSONObject(responseString);
        }
    }

    // 发送 GET 请求
    public static JSONObject get(String url, String token) throws IOException {
        Logger logger = Logger.getLogger(HttpUtils.class.getName());
        logger.info("Sending GET request to URL: " + url);
        Request request = new Request.Builder()
                .url(url)
                .get()
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + token)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()){
                logger.warning("Unexpected response code: " + response);
                throw new IOException("Unexpected code " + response);
            }

            ResponseBody responseBody = response.body();
            if (responseBody == null){
                logger.warning("Empty response body");
                throw new IOException("Empty response body");
            }

            logger.info("开始================================");
            String string = responseBody.string();
            System.out.println(string + "\n");
            logger.info("结束================================");


            return new JSONObject();
        }
    }

    // 发送流式 POST JSON 请求
    public static SseEmitter streamPostJson(String url, String jsonBody, String token) {
        Logger logger = Logger.getLogger(HttpUtils.class.getName());
        SseEmitter emitter = new SseEmitter(100_000L);
        new Thread(() -> {
            try {
                logger.info("Sending POST request to URL: " + url);

                RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .addHeader("Content-Type", "application/json")
                        .addHeader("Authorization", "Bearer " + token)
                        .build();

                Response response = client.newCall(request).execute();
                if (!response.isSuccessful()) {
                    logger.warning("Unexpected response code: " + response);
                    emitter.onError(Throwable::printStackTrace);
                    return;
                }

                ResponseBody responseBody = response.body();
                if (responseBody == null) {
                    logger.warning("Empty response body");
                    emitter.complete();
                    return;
                }

                BufferedSource source = responseBody.source();
                logger.info("开始================================");
                while (!source.exhausted()) {
                    String line = source.readUtf8Line();
                    if (line == null) break;
                    if (line.startsWith("data:")) {
                        String data = line.substring(5).trim();
                        if (data.startsWith("{") && data.endsWith("}")) {
                            JSONObject jsObj = JSONUtil.parseObj(data).getJSONObject("data");
                            if(jsObj != null) {
                                String content = jsObj.getStr("content");
                                System.out.print(content);
                                emitter.send(SseEmitter.event().name("message").data(content));
                            }
                        }
                    }
                }
                System.out.println("\n");
                logger.info("结束================================");
                emitter.complete();
            } catch (Exception e) {
                logger.warning("Error during streaming: " + e.getMessage());
                emitter.completeWithError(e);
            }
        }).start();

        return emitter;
    }

    // 新增：登录接口调用方法
    public static JSONObject login(String url, String username, String password) throws IOException {
        JSONObject loginJson = new JSONObject();
        loginJson.set("username", username);
        loginJson.set("password", password);

        RequestBody body = RequestBody.create(
                JSONUtil.toJsonStr(loginJson),
                MediaType.get("application/json; charset=utf-8")
        );

        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Login failed with code: " + response.code());

            ResponseBody responseBody = response.body();
            if (responseBody == null) throw new IOException("Empty response body");

            return new JSONObject(responseBody.string());
        }
    }

    /**
     * 上传文件到指定 URL
     */
    public static JSONObject uploadFile(String url, MultipartFile file, String token) throws IOException {
        Logger logger = Logger.getLogger(HttpUtils.class.getName());
        logger.info("Uploading file to URL: " + url + ", filename: " + file.getOriginalFilename());

        okhttp3.RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart(
                        "file",
                        file.getOriginalFilename(),
                        RequestBody.create(MediaType.parse("application/octet-stream"), file.getBytes())
                )
                .build();

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .addHeader("Authorization", "Bearer " + token)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                logger.warning("File upload failed with response code: " + response);
                throw new IOException("Unexpected code " + response);
            }
            ResponseBody responseBody = response.body();
            if (responseBody == null) {
                logger.warning("Empty response body received");
                throw new IOException("Empty response body");
            }
            String responseString = responseBody.string();
            logger.info("File upload successful, response: " + responseString);
            return new JSONObject(responseString);
        }
    }

    /**
     * 下载远程图片或文件，并写入到 HttpServletResponse 输出流中
     */
    public static void downloadFileToResponse(String url, String token, HttpServletResponse response) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .get()
                .addHeader("Authorization", "Bearer " + token)
                .build();

        try (Response responseFromServer = client.newCall(request).execute()) {
            if (!responseFromServer.isSuccessful()) throw new IOException("Unexpected code " + responseFromServer);

            ResponseBody responseBody = responseFromServer.body();
            if (responseBody == null) throw new IOException("Empty response body");

            // 设置响应头类型为图片类型（根据实际需要可扩展）
            response.setContentType(responseBody.contentType().toString());

            try (InputStream inputStream = responseBody.byteStream();
                 OutputStream outputStream = response.getOutputStream()) {

                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
        }
    }

    /**
     * 发送 POST 请求并获取二进制文件流
     */
    public static InputStream postFileStream(String url, String jsonBody, String token) throws IOException {
        Logger logger = Logger.getLogger(HttpUtils.class.getName());
        logger.info("Sending POST request to URL: " + url);
        RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json; charset=utf-8"));
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization", "Bearer " + token)
                .build();

        Response response = client.newCall(request).execute();
        if (!response.isSuccessful()) {
            logger.warning("Unexpected response code: " + response);
            throw new IOException("Unexpected code " + response);
        }
        ResponseBody responseBody = response.body();
        if (responseBody == null) {
            logger.warning("Empty response body");
            throw new IOException("Empty response body");
        }
        return responseBody.byteStream();
    }


}
